iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0

昨天有介紹到陣列的基礎,怎麼使用陣列,今天我們就繼續往後囉

記憶體中的陣列

基本類型陣列:

public class ArrayInRam {

	public static void main(String[] args) {
		
		//定義並初始化陣列
		int[] a = {10, 20 ,30};
		
		int[] b = new int[4];
		
		b = a;
	}

}

定義並初始化陣列時記憶體配置:

https://ithelp.ithome.com.tw/upload/images/20230929/20163139JmObvKe5Zb.png

a值賦給b後的記憶體配置:

https://ithelp.ithome.com.tw/upload/images/20230929/20163139wDD1mrdPIw.png

heap 記憶體中,第一個陣列具有兩個參照,第二個陣列失去了參照,變成垃圾,但長度依然不變,等到垃圾回收機制後才會消失

參考型態陣列:

class Person{
			
    public int age ;

    public double height;

    public void info() {
        System.out.println("我的年齡是:" + age + ",我的身高是:" + height );
    }

}
public class ReferenceArrayDemo {
	
	public static void main (String[] args) {
		
		
		Person[] students;
		
		students = new Person[2];
		
		Person jack = new Person();
		jack.age = 15;
		jack.height = 165;
		
		Person rose = new Person();
		rose.age = 18;
		rose.height = 158;
		
		students[0] = jack;
		students[1] = rose;
		jack.info();
		students[1].info();
		
		
	}
}

以下介紹程式碼的執行過程

記憶體配置:

執行 Person[] students 只有在stack 記憶體中定義了一個參考變數,就是一個指位器,未指向任何有效的記憶體區:

https://ithelp.ithome.com.tw/upload/images/20230929/20163139pXFDjUzilt.png

students = new Person[2]; 進行動態初始化,預設值為null,相當於定義了兩的person變數變數未指向任和有效的記憶體,所以還不能使用

https://ithelp.ithome.com.tw/upload/images/20230929/20163139u6HtIXfvZv.png

Person jack = new Person();
jack.age = 15;
jack.height = 165;
	
Person rose = new Person();
rose.age = 18;
rose.height = 158;

上面程式碼定義了jack 和rose兩個Person 實例,此時students 陣列的兩個元素依然是null
https://ithelp.ithome.com.tw/upload/images/20230929/20163139ZcIpkp9S5u.png

students[0] = jack;
students[1] = rose;

jack 賦值給students陣列的第一個元素,rose 賦值給第二個元素,students陣列的兩個元素會指向有效的記憶體區,此時jack 和students[0] 都指向同一個記憶體區,所以通過jack或students[0] 來存取Person 實例 的實例變數和方法完全一樣,所以修改也是修改同一個記憶體區,必互相影響。

https://ithelp.ithome.com.tw/upload/images/20230929/20163139OuBNPkouE2.png

二維陣列

二維陣列更方便處理較複雜的運算。

資料型態 陣列名稱[][];
陣列名稱=new 資料型態[列的個數][行的個數];  //而列的個數一定要填
int[][] matrix;  // 宣告
matrix = new int[2][3];//使陣列matrix 可存放2列3行的記憶體空間

Java根本沒有所謂的多維陣列!它只是不斷的在一維陣列中塞另一個陣列!

https://ithelp.ithome.com.tw/upload/images/20230929/20163139aU46a0OYJi.png

初始化的方法跟一維陣列相同,每列數量可不固定

int[][] arr11 = {{11,12}, {21,22,23}, {31,32}};
int[][] arr21 = new int[3][];
arr21[0]= new int[] {11,12};
arr21[1]= new int[] {21,22,23};
arr21[2]= new int[] {31,32};

用for 迴圈取出每一個成員

//印出每一個元素
for(int i = 0; i < arr11.length; i++ ) {
	for(int j = 0; j < arr11[i].length; j++ ) {
		System.out.println(arr11[i][j]);
	}
}

好用的方法

很多陣列相關方法都定義在Arrays裡,Arrays放在java.util套件中,使用前別忘了import:

import java.util.Arrays;
  1. 快速印出所有元素 Arrays.toString(Object[])
int[] array = { 2, 3, 5, 8, 13 };
System.out.println(Arrays.toString(array));
/*
執行結果:[ 2, 3, 5, 8, 13]
*/
  1. 複製陣列
    a. clone()
    可以快速的複製一個一模一樣的資料的陣列物件,與原陣列佔用不同記憶體,彼此獨立。

    int[] array = { 2, 3, 5, 8, 13 };
    int[] array2 = array.clone();
    array[0]=555;
    System.out.println(Arrays.toString(array));//[555, 3, 5, 8, 13]
    System.out.println(Arrays.toString(array2));//[2, 3, 5, 8, 13
    

    b. type[] copyOf(type[] original ,int length)

    將複製一個新的陣列物件,length是新陣列的長度。如果length 小於原本的陣列長度:新陣列就是原陣列前面的 length 元素 ; 如果length 小於原本的陣列長度:新陣列就是原陣列後面補上type的初始值

    c. type[] copyOfRange(type[] original ,int from, int to)
    跟上面類似取區間

  2. 填滿陣列元素 Arrays.fill(Object[],value
    可以把陣列全部用value填滿,常用於陣列初始化。

    int[] array = new int[10];
    System.out.println(Arrays.toString(array));
    Arrays.fill(array, -1);  // 以 -1 填滿 array
    System.out.println(Arrays.toString(array));
    /*
     執行結果:
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
    */
    
  3. 陣列排序 Arrays.sort(Object[]) 把陣列從小排到大

    int[] array = {50,1,-999,6000,77,3,50,0};
    System.out.println(Arrays.toString(array));
    Arrays.sort(array);
    System.out.println(Arrays.toString(array));
    /*
    執行結果:
    [50, 1, -999, 6000, 77, 3, 50, 0]
    [-999, 0, 1, 3, 50, 50, 77, 6000]
    */
    
  4. 陣列搜尋 Arrays.binarySearch(Object[],key)
    利用binarySearch搜尋陣列中目標key的索引值,因為是用binarySearch實做,所以陣列『必須已排序好(遞 增)』。

    int[] array = {50,1,-999,6000,77,3,50,0};
    System.out.println(Arrays.toString(array));
    Arrays.sort(array);
    System.out.println(Arrays.toString(array));
    System.out.println(Arrays.binarySearch(array, 77));
    System.out.println(Arrays.binarySearch(array, 2000));
    /*
     執行結果:
     [50, 1, -999, 6000, 77, 3, 50, 0]
     [-999, 0, 1, 3, 50, 50, 77, 6000]
     6    // 77 位在索引值6的位置
     -8   // 2000 不存在陣列中
    */
    
  5. 陣列相等 Arrays.equals(Object[],Object[])
    測試兩陣列是否相等,回傳布林值(true or false)。
    相等的條件:每個陣列元素的值、順序、長度都完全一樣,若 reference 指到同一物件視為相等,都為 null 也視為相等。

    
    int[] array = { 5, 6, 7 };
    int[] array2 = array.clone();
    System.out.println(Arrays.equals(array, array2));
    array[0] = 1;
    System.out.println(Arrays.equals(array, array2));
    array = array2;
    System.out.println(Arrays.equals(array, array2));
    array = null;
    array2 = null;
    System.out.println(Arrays.equals(array, array2));
    /*
     執行結果:
     true   // array2 是 array 複製過來的,所以資料完全一樣,故相等
     false  // array變成{1,6,7},array2還是{5,6,7},不相等
     true   // array 指到 array2的物件,故兩個reference相同,相等
     true   // 兩個皆為 null 視為相等
    */
    

    更多的方法可以參考:

    https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html


上一篇
Day13 陣列(Array)I
下一篇
Day 15 類別和物件
系列文
玩轉Java:從基礎打造你的程式超能力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言